#include "delay.h"

// TIM_HandleTypeDef tim7;
// static uint32_t _count = 0;

/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    /** Configure the main internal regulator output voltage
     */
    __HAL_RCC_PWR_CLK_ENABLE();
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

    /** Initializes the RCC Oscillators according to the specified parameters
     * in the RCC_OscInitTypeDef structure.
     */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_LSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.LSEState = RCC_LSE_ON; // 一定要注意，必须要配置LSE使能
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLM = 4;
    RCC_OscInitStruct.PLL.PLLN = 168;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
    RCC_OscInitStruct.PLL.PLLQ = 7;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        Error_Handler();
    }

    /** Initializes the CPU, AHB and APB buses clocks
     */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
    {
        Error_Handler();
    }
}

// void _tim7_update_callback(TIM_HandleTypeDef *htim)
// {
//     if (htim->Instance == TIM7)
//     {
//         _count++; // 单纯自动增1
//     }
// }

// // 以定时器7为例
// static void tim7_init(uint16_t psc, uint16_t arr)
// {
//     __HAL_RCC_TIM7_CLK_ENABLE(); // 开启定时器7的时钟

//     tim7.Instance = TIM7;                                        // 指向定时器6
//     tim7.Init.Prescaler = psc - 1;                               // 分频系数
//     tim7.Init.Period = arr - 1;                                  // 设置ARR自动重载值（需要注意，设置的值的问题）
//     tim7.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;            // 不分频（1分频）
//     tim7.Init.CounterMode = TIM_COUNTERMODE_UP;                  // 只支持向上计数
//     tim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; // 使能自动重载值

//     HAL_TIM_Base_Init(&tim7);

//     HAL_TIM_RegisterCallback(&tim7, HAL_TIM_PERIOD_ELAPSED_CB_ID, _tim7_update_callback);

//     HAL_NVIC_SetPriority(TIM7_IRQn, 4, 0);
//     HAL_NVIC_EnableIRQ(TIM7_IRQn); // 开启定时器6的NVIC

//     // 开启定时
//     HAL_TIM_Base_Start_IT(&tim7);
// }

// /**
//  * 定时器7的全局中断函数
//  */
// void TIM7_IRQHandler(void)
// {
//     HAL_TIM_IRQHandler(&tim7);
// }

void delay_init(void)
{
    HAL_Init();           // 1.必须HAL
    SystemClock_Config(); // 2.必须要完成系统时钟

    // 如果使用普通的定时，作为延迟的方式，使用中断的处理，可能会是被打断，导致不准确
    // tim7_init(84, 1000); // 在进行其他的配置
}

/**
 * 毫秒级别延迟
 */
void delay_ms(uint32_t ms)
{
    // uint32_t start = _count; // 先记录一下
    // while ((_count - start) < ms)
    //     ;
    HAL_Delay(ms); // 在非RTOS的情况下，可以直接使用
}

/**
 * 微秒级别延迟
 */
void delay_us(uint32_t us)
{
    // 构建us级别的延迟
    // 假如，SysTick的时钟主频是168M -> Val的自动减1的时间就是(1/168) us

    uint32_t start = SysTick->VAL; // VAL 寄存器

    uint32_t i = (us % 1000) * ((SysTick->LOAD + 1) / 1000);
    uint32_t dVal = 0;

    do
    {
        if (start > SysTick->VAL)
        {
            dVal = (start - SysTick->VAL);
        }
        else
        {
            dVal = (start - 0) + (SysTick->LOAD - SysTick->VAL);
        }
    } while (dVal < i);

    // 延迟ms部分
    if (us >= 1000)
    {
        uint32_t ms = us / 1000;
        delay_ms(ms);
    }
}
